package leetcode.lru;

import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @version v1.0
 * @description LinkedHashMap构造参数accessOrder的示例
 * HashMap 大家都清楚，底层是 数组 + 红黑树 + 链表 （不清楚也没有关系），同时其是无序的，
 * 而 LinkedHashMap 刚好就比 HashMap 多这一个功能，就是其提供 有序，
 * 并且，LinkedHashMap的有序可以按两种顺序排列，一种是按照插入的顺序，一种是按照读取的顺序（这个题目的示例就是告诉我们要按照读取的顺序进行排序），
 * 而其内部是靠 建立一个双向链表 来维护这个顺序的，在每次插入、删除后，都会调用一个函数来进行 双向链表的维护
 * 作者：jeromememory
 * 链接：https://leetcode-cn.com/problems/lru-cache/solution/yuan-yu-linkedhashmapyuan-ma-by-jeromememory/
 * 来源：力扣（LeetCode）
 * 著作权归作者所有。商业转载请联系作者获得授权，非商业转载请注明出处。
 * @date Created in 2021-07-05
 */
public class LRUCacheLinkedHashMapContructorParamTest {
    /**
     * LinkedHashMap构造参数accessOrder的说明：   false： 基于插入顺序     true：  基于访问顺序
     * 上面的代码打印结果为：abcd，很正常，按照加入的顺序打印
     */
    /*public static void main(String[] args) {
        Map<String, String> map = new LinkedHashMap<String, String>(16, 0.75f, true);
        map.put("1", "a");
        map.put("2", "b");
        map.put("3", "c");
        map.put("4", "d");

        for (Iterator<String> iterator = map.values().iterator(); iterator
                .hasNext(); ) {
            String name = iterator.next();
            System.out.print(name);
        }
    }*/

    /**
     * LinkedHashMap构造参数accessOrder的说明：
     * accessOrder依旧是true：  基于访问顺序
     * 打印结果为：cdab
     * 这就是基于访问的顺序，get一个元素后，这个元素被加到最后(使用了LRU 最近最少被使用的调度算法)
     */
    public static void main(String[] args) {
        //注意true false的区别
        Map<String, String> map = new LinkedHashMap<String, String>(16, 0.75f, true);
//        Map<String, String> map = new LinkedHashMap<String, String>(16, 0.75f, false);
        map.put("1", "a");
        map.put("2", "b");
        map.put("3", "c");
        map.put("4", "d");

        /**
         * 断点打在 map.get("1")处 Force Step into
         * 核心是afterNodeAccess方法
         * if (accessOrder) afterNodeAccess(e);//move node to last
         * 其作用就是在访问元素之后，将该元素放到双向链表的尾巴处(所以这个函数只有在按照读取的顺序的时候才会执行)
         */
        map.get("1");
        map.get("2");

        for (Iterator<String> iterator = map.values().iterator(); iterator
                .hasNext(); ) {
            String name = (String) iterator.next();
            System.out.print(name);
        }
    }
}
